package test.service.analysis;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math3.distribution.NormalDistribution;
import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;

/**
 * @Description TODO(这里用一句话描述这个类的作用)
 *
 * @author liuqinghua
 * @date 2023-9-11
 */
public class Ztfb {
    /**
     * 获取平均值
     *
     * @param bigDecimals 源数据
     * @return
     */
    public static BigDecimal getAvg(List<BigDecimal> bigDecimals) {
        BigDecimal mean = bigDecimals.stream().reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal(bigDecimals.size()), BigDecimal.ROUND_DOWN, 2);
        return mean;
    }

    /**
     * 获取标准差
     *
     * @param data 源数据
     * @param mean 平均值
     * @return
     */
    public static BigDecimal getStandDev(List<BigDecimal> data, BigDecimal mean) {
        BigDecimal variance = data.stream().map(d -> d.subtract(mean).pow(2)).reduce(BigDecimal.ZERO, BigDecimal::add)
                .divide(new BigDecimal(data.size()), BigDecimal.ROUND_DOWN, 4);
        BigDecimal stdDev = BigDecimal.valueOf(Math.sqrt(variance.doubleValue())).setScale(4, BigDecimal.ROUND_DOWN);
        return stdDev;
    }

    /**
     * 正太分布
     * 
     * @param data   源数据
     * @param mean   平均值
     * @param stdDev 标准差
     * @return
     */
    public static BigDecimal getNormalDistribution(BigDecimal data, BigDecimal mean, BigDecimal stdDev) {
        NormalDistribution normalDistribution = new NormalDistribution(mean.doubleValue(), stdDev.doubleValue());
        double result = normalDistribution.cumulativeProbability(data.doubleValue());
        BigDecimal b = new BigDecimal(result).setScale(4, BigDecimal.ROUND_DOWN);
        return b;
    }

    public static void main(String[] args) {
        List<BigDecimal> list = new ArrayList<BigDecimal>();
        list.add(new BigDecimal(182));
        list.add(new BigDecimal(175));
        list.add(new BigDecimal(175));
        list.add(new BigDecimal(175));
        list.add(new BigDecimal(173));
        list.add(new BigDecimal(180));
        list.add(new BigDecimal(177));
        list.add(new BigDecimal(190));
        list.add(new BigDecimal(169));
        list.add(new BigDecimal(183));
        list.add(new BigDecimal(170));
        list.add(new BigDecimal(183));
        list.add(new BigDecimal(178));
        list.add(new BigDecimal(185));
        BigDecimal mean = getAvg(list);
        System.out.println("平均数：" + mean);
        BigDecimal stdDev = getStandDev(list, mean);
        System.out.println("标准差：" + stdDev);

        mean = new BigDecimal("178.21");
        stdDev = new BigDecimal("5.95");

        List<BigDecimal> list2 = new ArrayList<BigDecimal>();
        list2.add(new BigDecimal(140));
        list2.add(new BigDecimal(145));
        list2.add(new BigDecimal(150));
        list2.add(new BigDecimal(155));
        list2.add(new BigDecimal(160));
        list2.add(new BigDecimal(165));
        list2.add(new BigDecimal(170));
        list2.add(new BigDecimal(175));
        list2.add(new BigDecimal(180));
        list2.add(new BigDecimal(185));
        list2.add(new BigDecimal(190));
        list2.add(new BigDecimal(195));
        list2.add(new BigDecimal(200));
        list2.add(new BigDecimal(205));
        list2.add(new BigDecimal(210));

        double sigma = 5.95d;
        double mu = 178.21;

        for (BigDecimal x : list2) {
            double v = x.doubleValue();
            double probability = (1 / (sigma * Math.sqrt(2 * Math.PI)))
                    * Math.exp(-Math.pow((v - mu), 2) / (2 * Math.pow(sigma, 2)));
//            BigDecimal yvalue = getNormalDistribution(x, mean, stdDev);
            System.out.println(new BigDecimal(probability).setScale(6, BigDecimal.ROUND_DOWN));
//            System.out.println("---------");
//            System.out.println(x + "," + probability);
        }

        double[] values = new double[list.size()];
        for (int i = 0; i < list.size(); i++) {
            values[i] = list.get(i).doubleValue();
        }
        System.out.println(new StandardDeviation().evaluate(values));
    }

}
